package com.wz.datachannel.view;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;

public class PhotoEditView extends View {

	public PhotoEditView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public PhotoEditView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public PhotoEditView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}
	
	Object mlock = new Object();
	Bitmap mbitmap = null;
	float  mzoom = 1;
	Rect   mrect = new Rect();
	Rect   drect = new Rect();
	
	public void openImageFile(String filename){
		try{
			synchronized(mlock){
				if(mbitmap!=null && !mbitmap.isRecycled()){
				   mbitmap.recycle();
				   mbitmap = null;
				}			
				mbitmap = readImageFile(filename,800,800,600);
				if (mbitmap!=null){
					setVisibility(View.VISIBLE);
					mrect.left = 0;
					mrect.top  = 0;
					mrect.right  = mbitmap.getWidth();
					mrect.bottom  = mbitmap.getHeight();				
					drect.left = 0; 
					drect.top  = 0;		
					mzoom = 1; 
					if (width > 0){
						float x = (float)mrect.right / width;
						float y = (float)mrect.bottom / height;				
						mzoom = (x < y ? x:y);				
						updateRect(mzoom);
					}
				}	
			}
			postInvalidate();
		}catch(Exception e){
			;
		}
	}
	
	public void close(){
		synchronized(mlock){
			if(mbitmap!=null && !mbitmap.isRecycled()){			
			   mbitmap.recycle();
			   mbitmap = null;	
			   setVisibility(View.INVISIBLE);
			}
		}
	}
	
	private Bitmap readImageFile(String path,int size,int w,int h){
		Bitmap bitmap = null;
		try{
	        // 取得图片   
	        InputStream temp = new FileInputStream(path);  
	        BitmapFactory.Options options = new BitmapFactory.Options();  
	        // 这个参数代表，不为bitmap分配内存空间，只记录一些该图片的信息（例如图片大小），说白了就是为了内存优化   
	        options.inJustDecodeBounds = true;
	        // 通过创建图片的方式，取得options的内容（这里就是利用了java的地址传递来赋值）   
	        BitmapFactory.decodeStream(temp, null, options);  
	        // 关闭流
	        temp.close();  	  
	        // 生成压缩的图片   
	        int i = 0;  
	        while (true) {  
	            // 这一步是根据要设置的大小，使宽和高都能满足   
	            if ((options.outWidth >> i <= size)  
	                    && (options.outHeight >> i <= size)) {  
	                // 重新取得流，注意：这里一定要再次加载，不能二次使用之前的流！   
	                temp = new FileInputStream(path); 
	                // 这个参数表示 新生成的图片为原始图片的几分之一。   
	                options.inSampleSize = (int) Math.pow(2.0D, i);  
	                // 这里之前设置为了true，所以要改为false，否则就创建不出图片   
	                options.inJustDecodeBounds = false;
	                options.inScaled = true;
	                options.outWidth = w;
	                options.outHeight = h;
	                Rect outRect = new Rect(0,0,122,h);
	                bitmap = BitmapFactory.decodeStream(temp, outRect, options);
	                break;   
	            }  
	            i += 1;  
	        }  
	        return bitmap;  
		}catch(IOException e){
			e.printStackTrace();
			return null;
		}
	}
		
	public boolean takeImageToFile(String filename){
		Bitmap bitmap = takeImageToBitmap(width,height);
		if (bitmap == null)return false;
		return (saveToFile(filename,bitmap) != null);
	}
	public Bitmap takeImageToBitmap(){
		return takeImageToBitmap(width,height);
	}
	public Bitmap takeImageToBitmap(int w,int h){
		if (mbitmap==null || mbitmap.isRecycled()) return null;
		Bitmap bitmap=null,bitmap2=null;
		try{
			bitmap = Bitmap.createBitmap(mbitmap, drect.left, drect.top, drect.right - drect.left,drect.bottom - drect.top);
			bitmap2 = Bitmap.createScaledBitmap(bitmap, w, h, true);
			bitmap.recycle();
			return bitmap2;
		}catch(Exception e){
			if (bitmap!=null) bitmap.recycle();
		}
		return null;
	}
	
	public File saveToFile(String filepath,Bitmap mBitmap)  {
        try {
        	File f = new File(filepath);
            FileOutputStream fOut = null;
            fOut = new FileOutputStream(f);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 95, fOut);
            fOut.flush();
            fOut.close();
            mBitmap.recycle();
            return f;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch(Exception e){
        	;
        }finally{
        	if (!mBitmap.isRecycled()){
        		mBitmap.recycle();
        	}
        }
        return null;
	}
	
	private void doDraw(Canvas canvas){
		canvas.drawColor(0xFFAEAEAE);
		synchronized(mlock){
			if(mbitmap!=null && !mbitmap.isRecycled()){
				canvas.drawBitmap(mbitmap, drect, drawRect, null);				
			}
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		doDraw(canvas);
	}

	int width,height;
	RectF   drawRect = new RectF();
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
		// TODO Auto-generated method stub
		super.onSizeChanged(w, h, oldw, oldh);  
		width = w;
		height = h;
		float x = (float)mrect.right / width;
		float y = (float)mrect.bottom / height; 		
		mzoom = (x < y ? x:y);		
		updateRect(mzoom);
	}
	
	private void updateRect(float zoom){		
		updateRect(drect.left,drect.top,zoom); 
	}
	
	private boolean chkeckUpdateZoomRect(float zoom){		
		if (zoom < 0 ) return false;		
		int x = drect.left;
		int y = drect.top;
		if ((int)(x + width  * zoom) > mrect.right){
			x = (int)(mrect.right - width  * zoom);
			if (x < 0) return false;
		}		
		if ((int)(y + height * zoom) > mrect.bottom){			
			y = (int)(mrect.bottom - height  * zoom);
			if (y < 0) return false;
		}		
		updateRect(x,y,zoom);		
		return true;
	}
	
	private void updateRect(int x,int y,float zoom){		
		if (x < 0 ) {x=0;}
		if (y < 0 ) {y=0;}		
		if ((int)(x + width * zoom) > mrect.right){
			x = (int)(mrect.right - width * zoom);
		}
		if((int)(y + height * zoom) > mrect.bottom){
			y = (int)(mrect.bottom - height * zoom);
		}		
		drect.left = x;
		drect.top  = y;
		drect.right  = x + (int)(width * zoom);
		drect.bottom = y + (int)(height * zoom);	
		drawRect.left = 0;
		drawRect.top = 0;
		drawRect.right = width;
		drawRect.bottom = height;  		
		postInvalidate();
	}
	
	public void updateZoom(float num){
		if (chkeckUpdateZoomRect(mzoom - num)){
			mzoom += -num;
		}
	}
	
	int	  event;
	long  time;
	float startX=0,startY=0;
	int   lastX =0, lastY=0;
	
	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouchEvent(MotionEvent ev) {		
		try{			
			if(mbitmap==null || mbitmap.isRecycled()) return true;			    
			switch (ev.getAction()) {
			case MotionEvent.ACTION_DOWN:
				event = 1;				
				startX = ev.getX();
				startY = ev.getY();
				lastX = drect.left;
				lastY = drect.top;
				break;
			case MotionEvent.ACTION_MOVE:
				if(event==1){
					if (System.currentTimeMillis() - time > 20){				
						float x = startX - ev.getX();
						float y = startY - ev.getY();						
						updateRect((int)(lastX + x),(int)(lastY + y),mzoom);				
						time  = System.currentTimeMillis();	
					}
				}
				break;
			case MotionEvent.ACTION_CANCEL:
			case MotionEvent.ACTION_UP:
				event=0;
				break;
			}		
		}catch(Exception e){
			e.printStackTrace();
		}		
		return true;
	}

	
	public boolean onGenericMotionEvent(MotionEvent event){
		//输入源为可显示的指针设备，如：mouse pointing device(鼠标指针),stylus pointing device(尖笔设备)  
		if (0 != (event.getSource() & InputDevice.SOURCE_CLASS_POINTER)) {    
			  switch (event.getAction()) {  
			    // process the scroll wheel movement...处理滚轮事件  
			    case MotionEvent.ACTION_SCROLL:   
				    //获得垂直坐标上的滚动方向,也就是滚轮向下滚 
				    if( event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f){
				    	updateZoom(-0.05f);
				    }else{
				       	//获得垂直坐标上的滚动方向,也就是滚轮向上滚
				       	updateZoom(0.05f);
				    }  
			        return true;  
			  }  
		 }  
		 return super.onGenericMotionEvent(event);  
	}
	
	
	public boolean isOpen(){
		return !(mbitmap==null || mbitmap.isRecycled());
	}
}
